package com.hb.config;

import com.hb.evaluator.SpittlePermissionEvaluator;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.access.expression.method.DefaultMethodSecurityExpressionHandler;
import org.springframework.security.access.expression.method.MethodSecurityExpressionHandler;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.method.configuration.GlobalMethodSecurityConfiguration;

@Configuration
// 我们需要将 @EnableGlobalMethod-Security 注解的 prePostEnabled 属性设置为 true，从而启用使用 SpEL 的安全注解。
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class ExpressionMethodSecurityConfig extends GlobalMethodSecurityConfiguration {
    /**
     * 默认情况下，Spring Security 会配置为使用 DefaultMethodSecurityExpressionHandler，它会使用一个 DenyAllPermissionEvaluator 实例。
     * 顾名思义，DenyAllPermissionEvaluator 将会在 hasPermission() 方法中始终返回 false，拒绝所有的方法访问。但是，我们可以为 Spring Security
     * 提供另外一个 DefaultMethodSecurityExpressionHandler，让它使用我们自定义的 SpittlePermissionEvaluator，这需要重载
     * GlobalMethodSecurityConfiguration 的 createExpressionHandler 方法。现在，我们不管在任何地方的表达式中使用 hasPermission() 来保
     * 护方法，都会调用 SpittlePermissionEvaluator 来决定用户是否有权限调用方法。
     * @return
     */
    @Override
    protected MethodSecurityExpressionHandler createExpressionHandler() {
        DefaultMethodSecurityExpressionHandler expressionHandler = new DefaultMethodSecurityExpressionHandler();
        expressionHandler.setPermissionEvaluator(new SpittlePermissionEvaluator());
        return expressionHandler;
    }
}
